#ifndef __ILIB_CORE_SMART_PTR_H_20120311__
#define __ILIB_CORE_SMART_PTR_H_20120311__

template <class T>
class iSmartPointer
{
public:
	inline iSmartPointer(T* obj=NULL)
		:m_obj(obj)
	{
		if(m_obj) m_obj->add_ref();
	}
	inline ~iSmartPointer()
	{
		if(m_obj)
			m_obj->release_ref();

		m_obj = NULL;
	}
	inline iSmartPointer(const iSmartPointer& sp)
	{
		m_obj = sp.m_obj;
		if(m_obj) 
			m_obj->add_ref();
	}
	inline iSmartPointer& operator =(const iSmartPointer& sp)
	{
		if(m_obj)
			m_obj->release_ref();

		m_obj = sp.m_obj;
		if(m_obj)
			m_obj->add_ref();

		return *this;
	}
	inline iSmartPointer& operator=(T* obj)
	{
		if(m_obj)
			m_obj->release_ref();

		m_obj = obj;
		if(m_obj)
			m_obj->add_ref();
		return *this;
	}
	inline operator T*() { return m_obj; }

	inline T* operator->() { return m_obj; }

	inline T* operator*()  { return *m_obj;}
private:
	T*	m_obj;
};

template<class T, class L>
class iRefObject
{
public:
	iRefObject()
	{

	}

	inline int add_ref() 
	{ 
		m_lock.acquire();
		++m_counter;
		m_lock.release();
		return m_counter;
	}
	inline void release_ref()  
	{
		m_lock.acquire();
		--m_counter; 
		m_lock.release();
		if(0 == m_counter)
			this->on_destroy();
	}

private:
	virtual void on_destroy() = 0; 

protected:
	virtual ~iRefObject() {}

private:
	T	m_counter;
	L   m_lock;
};

#endif  //__ILIB_CORE_SMART_PTR_H_20120311__
